package cn.exrick.xboot.base.serviceimpl

import cn.exrick.xboot.base.entity.DepartmentUser
import cn.exrick.xboot.base.mapper.DepartmentUserMapper
import cn.exrick.xboot.base.service.IAreaService
import cn.exrick.xboot.base.service.IDepartmentUserService
import cn.exrick.xboot.base.vo.DepartmentUserVo
import cn.exrick.xboot.core.common.constant.CommonConstant
import cn.exrick.xboot.core.common.utils.PageUtil
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.utils.ToolUtil
import cn.exrick.xboot.core.common.vo.PageVo
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.entity.User
import cn.exrick.xboot.core.entity.UserRole
import cn.exrick.xboot.core.service.RoleService
import cn.exrick.xboot.core.service.UserService
import cn.exrick.xboot.core.service.mybatis.IUserRoleService
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.google.common.collect.Maps
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * 行业接口实现
 * @author Fei
 */
@Slf4j
@Service
@Transactional
open class IDepartmentUserServiceImpl : ServiceImpl<DepartmentUserMapper?, DepartmentUser?>(), IDepartmentUserService {

    @Autowired
    private lateinit var securityUtil: SecurityUtil

    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var iUserRoleService: IUserRoleService

    @Autowired
    private lateinit var roleService: RoleService

    @Autowired
    private lateinit var iAreaService: IAreaService



    override fun createDepartmentUser(departmentUser: DepartmentUser): Result<Any?>? {


        return try {


            if (ToolUtil.isNotEmpty(getOne(KtQueryWrapper(DepartmentUser::class.java).eq(DepartmentUser::unitCode, departmentUser.unitCode)))) {

                 return ResultUtil.error<Any>("当前登录代码已经存在!")
            }

            departmentUser.run {

                //1.添加用户
                val user = userService.save(User().apply {

                    username = unitCode
                    password = BCryptPasswordEncoder().encode("111111")
                    nickname = accountName
                    areaId = if (ToolUtil.isEmpty(departmentUser.areaId)) securityUtil.currUser.areaId else departmentUser.areaId
                })

                //2. 添加角色
                iUserRoleService.save(UserRole().apply {

                    roleId = roleService.getRoleIdByRoleName(if (iUserRoleService.findByUserId(securityUtil.currUser.id).map { role -> role.id }
                                    .contains(roleService.getRoleIdByRoleName(CommonConstant.ROLE_ADMIN))) CommonConstant.ROLE_CITY_UNIT_SYSTEM
                    else when (iAreaService.getById(securityUtil.currUser.areaId)?.areaLevel) {

                        1 -> {

                            if (departmentUser.type == 0) CommonConstant.ROLE_CITY_DEPARTMENT_UNIT else {

                                if (ToolUtil.isNotEmpty(departmentUser.areaId)) CommonConstant.ROLE_CITY_UNIT_SYSTEM else CommonConstant.ROLE_CITY_UNIT
                            }

                        }
                        2 -> {

                            if (departmentUser.type == 0) CommonConstant.ROLE_COUNTY_DEPARTMENT_UNIT else {

                                if (ToolUtil.isNotEmpty(departmentUser.areaId)) CommonConstant.ROLE_COUNTRY_UNIT_SYSTEM else CommonConstant.ROLE_COUNTRY_UNIT
                            }
                        }
                        else -> {

                            if (departmentUser.type == 0) CommonConstant.ROLE_TOWN_DEPARTMENT_UNIT else {

                                if (ToolUtil.isNotEmpty(departmentUser.areaId)) CommonConstant.ROLE_TOWN_UNIT_SYSTEM else CommonConstant.ROLE_TOWN_UNIT
                            }
                        }
                    })
                    userId = user.id
                })

                //3. 添加政府用户
                save(departmentUser.apply {

                    userId = user.id
                    createBy = securityUtil.currUser.id
                    areaId =  if (ToolUtil.isEmpty(departmentUser.areaId)) securityUtil.currUser.areaId else departmentUser.areaId
                    userLevel = iAreaService.getById(if (ToolUtil.isEmpty(departmentUser.areaId)) securityUtil.currUser.areaId else departmentUser.areaId)?.areaLevel
                })
            }

            ResultUtil.success("添加政府部门用户成功")
        }catch (e : Exception) {

            ResultUtil.error(e.message)
        }

    }

    override fun getDepartmentUserByUserId(userId: String): DepartmentUser? {

        return getOne(KtQueryWrapper(DepartmentUser::class.java).eq(DepartmentUser::userId, userId))
    }

    override fun resetPassword(id: String): Result<Any> {

        getById(id)?.run {

            userService.get(userId)?.let {

                it.password = BCryptPasswordEncoder().encode("111111")
                userService.update(it)
            }
        }

        return ResultUtil.success("重置密码成功")
    }


    override fun updateDepartmentUser(departmentUser: DepartmentUser): Result<Any?>? {


       return try {

           getById(departmentUser.id)?.run {

               //更新用户
               userService.get(userId)?.let {

                   userService.update(it.apply {

                       username = unitCode
                       nickname = accountName
                   })
               }

               //更新政府用户
               updateById(departmentUser)
           }

           ResultUtil.success("更新成功")
       }catch (e : Exception) {

           ResultUtil.error(e.message)
       }
    }


    override fun removeDepartmentUser(ids: Array<out String>): Result<Any?>? {

        return try {

            ids.forEach {

                getById(it)?.run {

                    //1.删除用户
                    userService.delete(userId)

                    //2.删除部门用户
                    removeById(it)
                }
            }

            ResultUtil.success("移除成功")
        }catch (e: Exception) {

            ResultUtil.error(e.message)
        }

    }

    override fun getDepartmentUserList(pageVo: PageVo, departmentUser: DepartmentUser, levelType: Int): Result<MutableMap<String, Any?>>? {


        val ktQueryWrapper = KtQueryWrapper(DepartmentUser::class.java)
                .eq(ToolUtil.isNotEmpty(departmentUser.areaId), DepartmentUser::areaId, departmentUser.areaId)
                .like(ToolUtil.isNotEmpty(departmentUser.accountName), departmentUser::accountName, departmentUser.accountName)
                .like(ToolUtil.isNotEmpty(departmentUser.unitCode), departmentUser::unitCode, departmentUser.unitCode)
                .eq(ToolUtil.isNotEmpty(departmentUser.type), departmentUser::type, departmentUser.type)
                .eq(departmentUser::createBy, securityUtil.currUser.id)
                .orderByAsc(DepartmentUser::createTime)
        when (levelType) {
            1 -> {
                ktQueryWrapper.eq(DepartmentUser::userLevel, if (iUserRoleService.findByUserId(securityUtil.currUser.id)
                                .map { role -> role.id }.toMutableList().contains(roleService.getRoleIdByRoleName(CommonConstant.ROLE_ADMIN)))
                    1 else iAreaService.getById(securityUtil.currUser.areaId)?.areaLevel)
            }
            else -> {
                ktQueryWrapper.eq(DepartmentUser::userLevel, iAreaService.getById(securityUtil.currUser.areaId)?.areaLevel?.plus(1))
            }
        }

        return ToolUtil.setListToNul(list(ktQueryWrapper))?.run {

            val result : MutableMap<String, Any?> = Maps.newHashMap()
            result["size"] = size
            result["content"] = PageUtil.listToPage(pageVo,  mapNotNull {

                DepartmentUserVo().apply {

                    ToolUtil.copyProperties(it, this)
                    areaName = iAreaService.getAreaFullNameByAreaId(areaId)
                    userLevelName = when (departmentUser.type) {

                         0-> {

                             when (it!!.userLevel) {
                                 1 -> {
                                     "市级政府"
                                 }
                                 2 -> {
                                     "县区级政府"
                                 }
                                 else -> {
                                     "乡镇级政府"
                                 }
                             }
                        }
                        else -> {

                            when (it!!.userLevel) {
                                1 -> {
                                    "市级监管部门"
                                }
                                2 -> {
                                    "县区级监管部门"
                                }
                                else -> {
                                    "乡镇级监管部门"
                                }
                            }
                        }
                    }

                }
            })

            ResultUtil.data(result, "获取数据成功")
        } ?: ResultUtil.error(201, "暂无数据")

    }

}